#include <iostream>
#include <thread>
#include <chrono>
#include <csignal>
#include <iomanip>
#include <sstream>
#include "ModbusDevice.hpp"
#include "MqttClient.hpp"

bool running = true;
void signalHandler(int) { running = false; }

// 自定义设备类，继承 MqttClient，重写回调函数
class MyDeviceMqtt : public MqttClient {
public:
    using MqttClient::MqttClient;

    void onConnect(int rc) override {
        if (rc == 0) {
            std::cout << "[MyDeviceMqtt] ✅ 已成功连接至云端\n";
            subscribe("/cmd/test");
        }
    }

    void onMessage(const std::string &topic, const std::string &payload) override {
        std::cout << "[MyDeviceMqtt] 📩 收到消息: " << topic << " => " << payload << "\n";
        publish("/data/reply", "{\"msg\": \"Hello from 2K300 device!\"}");
    }
};

int main() {
    signal(SIGINT, signalHandler);

    try {
        // 1️⃣ 初始化 Modbus 设备
        std::string device = "/dev/ttyS1";
        int baud = 4800;
        char parity = 'N';
        int data_bits = 8;
        int stop_bits = 1;
        int slave_id = 1;

        ModbusDevice modbus(device, baud, parity, data_bits, stop_bits, slave_id);
        modbus.SetResponseTimeout(1, 0);

        if (!modbus.ModbusConnect()) {
            std::cerr << "❌ 无法连接到 Modbus 设备\n";
            return -1;
        }
        std::cout << "[Modbus] ✅ 成功连接到传感器\n";

        // 2️⃣ 初始化 MQTT 客户端
        MyDeviceMqtt client("2K300", "47.109.28.214", 1883, "root", "$Yang20050701");
        if (!client.connect()) {
            std::cerr << "❌ 无法连接 MQTT Broker\n";
            return -1;
        }

        std::cout << "[System] ✅ 初始化完成，开始采集与上传...\n";

        // 3️⃣ 主循环：采集 + 上传
        uint16_t regs[2] = {0};
        while (running) {
            if (!modbus.ModbusReadRegisters(0x0000, 2, regs)) {
                std::cerr << "⚠️ 读取 Modbus 数据失败\n";
                continue;
            }

            float moisture = regs[0] / 10.0f;            
            float temperature = (int16_t)regs[1] / 10.0f; 

            // 格式化为 JSON
            std::ostringstream oss;
            oss << std::fixed << std::setprecision(1)
                << "{"
                << "\"moisture\": " << moisture << ", "
                << "\"temperature\": " << temperature
                << "}";

            std::string payload = oss.str();
            std::cout << "[Sensor] 🌱 湿度: " << moisture << " %, 温度: " << temperature << " °C\n";

            // 通过 MQTT 上传
            client.publish("/data/sensor", payload);

            std::this_thread::sleep_for(std::chrono::seconds(5));
        }

        std::cout << "[System] 📴 用户中断，正在退出...\n";
    } catch (const std::exception &e) {
        std::cerr << "[Error] " << e.what() << std::endl;
    }

    return 0;
}
